// compose 学习 https://juejin.cn/post/6989020415444123662#comment
// 终极compose函数封装方案 https://juejin.cn/post/6989815456416661534
/**
 * compose 函数
 * 组合 ———— 声明式数据流 ———— 是支撑函数式编程最重要的工具之一！
*/

// 接收多个函数
// 同步 compose(fn1, fn2, fn3....)
function compose(...fns) {
    return function composed(result) {
        var list = fns.slice(); // copy一份 不影响参数
        while (list.length > 0) {
            // 取出最后一位 并执行
            result = list.pop()(result)
        }
        // 执行完毕同步任务后返回结果
        return result
    }
}

const synchronization = function () {
    const fns = []
    let i = 10
    while (i) {
        // push
        const I = i
        fns.push((r) => {
            return r ? r + I : I
        })
        i--
    }
    return fns
}

const d = synchronization()

// console.log('compose 同步 ===> ', compose(...d)())

// 异步 compose(fn1, fn2, fn3....)
function composePrimise(...args) {
    const init = args.pop()
    return function (...fbs) {
        // 从最后一个开始处理
        return args.reverse().reduce(
            (sequence, func) => {
                // 拿到每一次执行的then的结果
                return sequence.then((result) => {
                    return func(result)
                })
            },
            // 初始then
            Promise.resolve(init(fbs))
        )
    }
}

let a = async () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('xhr1')
            resolve('xhr1')
        }, 5000)
    })
}

let b = async () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('xhr2')
            resolve('xhr2')
        }, 3000)
    })
}
let steps = [a, b] // 从右向左执行
let composeFn = composePrimise(...steps)
// console.log('composeFn ==> ', composeFn)
composeFn().then(res => {
    console.log('res ===> 最后的333')
})

